package org.fanlychie.jreflect.util;

import org.fanlychie.jreflect.operator.ConstructorOperator;
import org.fanlychie.jreflect.operator.FieldOperator;
import org.fanlychie.jreflect.operator.MethodOperator;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 操纵工具类
 * Created by fanlychie on 2019/7/25.
 */
public class BeanUtils {

    // 字段常驻内存
    private static final Map<Class<?>, FieldOperator> FIELD_OPERATOR_CACHE_MAP = new ConcurrentHashMap<>();

    // 方法常驻内存
    private static final Map<Class<?>, MethodOperator> METHOD_OPERATOR_CACHE_MAP = new ConcurrentHashMap<>();

    // 构造器常驻内存
    private static final Map<Class<?>, ConstructorOperator> CONSTRUCTOR_OPERATOR_CACHE_MAP = new ConcurrentHashMap<>();

    /**
     * 获得操作字段能力的实例
     *
     * @param pojoClass 任意的Class类型
     */
    public static FieldOperator fieldOperate(Class<?> pojoClass) {
        return fieldOperate(pojoClass, true, true, Object.class);
    }

    /**
     * 获得操作字段能力的实例
     *
     * @param pojoClass            任意的Class类型
     * @param accessibleStatic     是否允许访问Class的静态属性
     * @param accessibleSuperclass 是否递归查找Class的父类属性
     * @param stopClass            在递归查找时, 遇到此类则终止搜索字段
     */
    public static FieldOperator fieldOperate(Class<?> pojoClass, boolean accessibleStatic, boolean accessibleSuperclass, Class<?> stopClass) {
        FieldOperator operator = FIELD_OPERATOR_CACHE_MAP.get(pojoClass);
        if (operator == null) {
            operator = new FieldOperator(pojoClass, accessibleStatic, accessibleSuperclass, stopClass).init();
            FIELD_OPERATOR_CACHE_MAP.put(pojoClass, operator);
        }
        return operator;
    }

    /**
     * 获得操作方法能力的实例
     *
     * @param pojoClass 任意的Class类型
     */
    public static MethodOperator methodOperate(Class<?> pojoClass) {
        return methodOperate(pojoClass, true, true, Object.class);
    }

    /**
     * 获得操作方法能力的实例
     *
     * @param pojoClass            任意的Class类型
     * @param accessibleStatic     是否允许访问Class的静态属性
     * @param accessibleSuperclass 是否递归查找Class的父类属性
     * @param stopClass            在递归查找时, 遇到此类则终止搜索字段
     */
    public static MethodOperator methodOperate(Class<?> pojoClass, boolean accessibleStatic, boolean accessibleSuperclass, Class<?> stopClass) {
        MethodOperator operator = METHOD_OPERATOR_CACHE_MAP.get(pojoClass);
        if (operator == null) {
            operator = new MethodOperator(pojoClass, accessibleStatic, accessibleSuperclass, stopClass).init();
            METHOD_OPERATOR_CACHE_MAP.put(pojoClass, operator);
        }
        return operator;
    }

    /**
     * 获得操作构造器能力的实例
     *
     * @param pojoClass 任意的Class类型
     */
    public static ConstructorOperator constructorOperate(Class<?> pojoClass) {
        ConstructorOperator operator = CONSTRUCTOR_OPERATOR_CACHE_MAP.get(pojoClass);
        if (operator == null) {
            operator = new ConstructorOperator(pojoClass).init();
            CONSTRUCTOR_OPERATOR_CACHE_MAP.put(pojoClass, operator);
        }
        return operator;
    }

}